#include "util.h"

struct timespec currentTime()
{
    struct timespec ts;
    if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
    {
        ts.tv_sec = time(NULL);
        ts.tv_nsec = 0;
    }
    return ts;
}

long usecTime()
{
    struct timeval tv;
    gettimeofday(&tv, nullptr);
    long milliseconds_since_epoch = (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL);
    return milliseconds_since_epoch;
}

// 递归创建目录（如果不存在）
int create_dir_if_not_exists(const char *path) {
    char *path_copy = strdup(path); // 复制路径，因为 dirname() 可能修改输入
    char *dir = dirname(path_copy); // 提取目录部分（去掉文件名）

    // 检查目录是否存在
    struct stat st;
    if (stat(dir, &st) == 0) {
        free(path_copy);
        return S_ISDIR(st.st_mode) ? 0 : -1; // 如果是目录则成功
    }

    // 目录不存在，递归创建
    if (mkdir(dir, 0755) == -1 && errno != EEXIST) {
        perror("mkdir failed");
        free(path_copy);
        return -1;
    }

    free(path_copy);
    return 0;
}

// 创建稀疏文件
int create_sparse_file(const char *path, off_t size) {
    // 检查并创建目录
    if (create_dir_if_not_exists(path) == -1) {
        syslog(LOG_ERR, "Failed to create directory for %s\n", path);
        return -1;
    }

    // 创建文件并设置大小
    int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        syslog(LOG_ERR, "open failed: %s\n", strerror(errno));
        return -1;
    }

    if (ftruncate(fd, size) == -1) {
        syslog(LOG_ERR, "ftruncate failed: %s\n", strerror(errno));
        close(fd);
        return -1;
    }

    close(fd);
    return 0;
}